package com.bkgy.controller.outputRecord.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.controller.outputRecord.entity.RepBreakRecord;
import com.bkgy.controller.outputRecord.entity.pdo.WorkBreakReq;
import com.bkgy.controller.outputRecord.entity.pdo.WorkBreakRes;
import com.bkgy.controller.outputRecord.mapper.IOutputRecordMapper;
import com.bkgy.controller.outputRecord.service.IOutputRecordService;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
@RequiredArgsConstructor
public class OutputRecordServiceImpl extends ServiceImpl<IOutputRecordMapper, RepBreakRecord> implements IOutputRecordService {
    private final IOutputRecordMapper mapper;

    @Override
    public ResultData<WorkBreakRes> workBreak(WorkBreakReq req) {
        String lineName = req.getLineName();
        String dateType = req.getDateType();
        LambdaQueryWrapper<RepBreakRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepBreakRecord::getLineName, lineName).eq(RepBreakRecord::getDateType, dateType)
                .orderByDesc(RepBreakRecord::getOutMatWt).last(" FETCH FIRST 5 ROWS ONLY");
        List<RepBreakRecord> list = list(wrapper);
        List<WorkBreakRes> resList = new ArrayList<>();
        int i = list.size();
        for (RepBreakRecord record : list) {
            WorkBreakRes res = new WorkBreakRes();
            res.setNum(i--);
            String shijian = record.getShijian();
            Date d = DateUtil.getStringToDate(shijian.length() == 8 ? "yyyyMMdd" : "yyyyMM", shijian);
            res.setDate(DateUtil.getDateToString(d, shijian.length() == 8 ? "yyyy/MM/dd" : "yyyy/MM"));
            res.setWorkOut(record.getOutMatWt().setScale(1, RoundingMode.HALF_UP));
            res.setCrew(record.getCrew());
            resList.add(res);
        }
        Collections.reverse(resList);
        return ResultData.ResultDataSuccess(resList, resList.size());
    }

    @Override
    public ResultData<String> buildOutputRecord(String dateType) {
        String lineName = "tcm2280";
        LambdaQueryWrapper<RepBreakRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepBreakRecord::getLineName, lineName).eq(RepBreakRecord::getDateType, dateType);
        remove(wrapper);

        List<RepBreakRecord> newRecordList = new ArrayList<>();
        RepBreakRecord record = new RepBreakRecord();
        if ("month".equals(dateType)) {
            //月产量破记录
            List<RepBreakRecord> list = mapper.selectByMonth();
            for (RepBreakRecord r : list) {
                if (r.getOutMatWt().compareTo(record.getOutMatWt()) > 0) {
                    newRecordList.add(r);
                    record = r;
                    record.setLineName(lineName);
                    record.setDateType(dateType);
                }
            }
        } else if ("daily".equals(dateType)) {
            //日产破记录
            List<RepBreakRecord> list = mapper.selectByDaily();
            for (RepBreakRecord r : list) {
                if (r.getOutMatWt().compareTo(record.getOutMatWt()) > 0) {
                    newRecordList.add(r);
                    record = r;
                    record.setLineName(lineName);
                    record.setDateType(dateType);
                }
            }
        } else if ("day".equals(dateType)) {
            //白班破记录
            List<RepBreakRecord> list = mapper.selectByDay();
            for (RepBreakRecord r : list) {
                if (r.getOutMatWt().compareTo(record.getOutMatWt()) > 0) {
                    //查询当班班组
                    String crewStr = mapper.getTcm2280TopOneCrew(r.getShijian() + "080000");
                    r.setCrew(crewStr);
                    newRecordList.add(r);
                    record = r;
                    record.setLineName(lineName);
                    record.setCrew(crewStr);
                    record.setDateType(dateType);
                }
            }
        } else if ("night".equals(dateType)) {
            RepBreakRecord topRecord = new RepBreakRecord();//最高记录
            RepBreakRecord tempRecord = new RepBreakRecord();
            Date beginDate = null;//班第一条记录时间
            Date lastDate = null;//班最后一条记录时间
            List<RepBreakRecord> list = mapper.selectByNight();
            if (list.size() > 0) {
                beginDate = DateUtil.getStringToDate("yyyyMMddHHmmss", list.get(0).getShijian());
                lastDate = beginDate;
            }
            Date currentDate = null;
            for (RepBreakRecord r : list) {
                currentDate = DateUtil.getStringToDate("yyyyMMddHHmmss", r.getShijian());
                //当前时间与上一时间差大于11小时，说明不是本次夜班的记录
                if (currentDate.getTime() - lastDate.getTime() > 1000 * 60 * 60 * 11) {
                    //超过记录
                    if (tempRecord.getOutMatWt().compareTo(topRecord.getOutMatWt()) > 0) {
                        tempRecord.setShijian(DateUtil.getDateToString(beginDate, "yyyyMMdd"));
                        newRecordList.add(tempRecord);
                        topRecord = tempRecord;
                    }
                    tempRecord = r;
                    beginDate = DateUtil.getStringToDate("yyyyMMddHHmmss", r.getShijian());
                    lastDate = beginDate;
                } else {
                    tempRecord.setLineName(lineName);
                    tempRecord.setDateType(dateType);
                    tempRecord.setCrew(r.getCrew());
                    tempRecord.setOutMatWt(tempRecord.getOutMatWt().add(r.getOutMatWt()));
                    lastDate = currentDate;
                }
            }
            if (tempRecord.getOutMatWt().compareTo(topRecord.getOutMatWt()) > 0) {
                tempRecord.setShijian(DateUtil.getDateToString(currentDate, "yyyyMMdd"));
                newRecordList.add(tempRecord);
            }
        }
        if (newRecordList.size() > 0) saveBatch(newRecordList);
        return ResultData.ResultDataSuccess("success");
    }

    @Override
    public void buildRecordJob() {
        String lineName = "tcm2280";
        //8点计算夜班生产记录；19点计算白班生产记录；0点计算前一日日产记录；1日计算上月产量记录
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (hour == 8) {
            //上一日19点--今日8点产量
            String endDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMddHH000000");
            cal.add(Calendar.HOUR_OF_DAY, -13);
            String beginDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMddHH000000");
            BigDecimal outputWtRecord = mapper.getTopRecordCrew(lineName, "night");
            BigDecimal outputAct = mapper.getTcmOutputWt(beginDate, endDate);
            if (outputAct.compareTo(outputWtRecord) > 0) {
                //破历史记录
                String crew = mapper.getTcm2280TopOneCrew(beginDate);
                RepBreakRecord outputRecord = new RepBreakRecord();
                outputRecord.setLineName(lineName);
                outputRecord.setCrew(crew);
                outputRecord.setDateType("night");
                outputRecord.setShijian(DateUtil.getDateToString(cal.getTime(), "yyyyMMdd"));
                outputRecord.setOutMatWt(outputAct);
                save(outputRecord);
            }
        } else if (hour == 19) {
            //8点--19点产量
            String endDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMddHH000000");
            cal.add(Calendar.HOUR_OF_DAY, -11);
            String beginDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMddHH000000");
            BigDecimal outputWtRecord = mapper.getTopRecordCrew(lineName, "day");
            BigDecimal outputAct = mapper.getTcmOutputWt(beginDate, endDate);
            if (outputAct.compareTo(outputWtRecord) > 0) {
                //破历史记录
                String crew = mapper.getTcm2280TopOneCrew(beginDate);
                RepBreakRecord outputRecord = new RepBreakRecord();
                outputRecord.setLineName(lineName);
                outputRecord.setCrew(crew);
                outputRecord.setDateType("day");
                outputRecord.setShijian(DateUtil.getDateToString(cal.getTime(), "yyyyMMdd"));
                outputRecord.setOutMatWt(outputAct);
                save(outputRecord);
            }
        } else if (hour == 0) {
            //检查上一天产量是否破记录
            String endDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMdd");
            cal.add(Calendar.DAY_OF_MONTH, -1);
            String beginDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMdd");
            BigDecimal outputWtRecord = mapper.getTopRecordCrew(lineName, "daily");
            BigDecimal outputAct = mapper.getTcmOutputWt(beginDate, endDate);
            if (outputAct.compareTo(outputWtRecord) > 0) {
                //破历史记录
                RepBreakRecord outputRecord = new RepBreakRecord();
                outputRecord.setLineName(lineName);
                outputRecord.setDateType("daily");
                outputRecord.setShijian(DateUtil.getDateToString(cal.getTime(), "yyyyMMdd"));
                outputRecord.setOutMatWt(outputAct);
                save(outputRecord);
            }
            if (day == 1) {
                //1日检查上月是否破记录
                beginDate = DateUtil.lastMonthFirstDay("yyyyMMdd");
                endDate = DateUtil.thisMonthFirstDay("yyyyMMdd");
                outputWtRecord = mapper.getTopRecordCrew(lineName, "month");
                outputAct = mapper.getTcmOutputWt(beginDate, endDate);
                if (outputAct.compareTo(outputWtRecord) > 0) {
                    //破历史记录
                    RepBreakRecord outputRecord = new RepBreakRecord();
                    outputRecord.setLineName(lineName);
                    outputRecord.setDateType("month");
                    outputRecord.setShijian(beginDate.substring(0, 6));
                    outputRecord.setOutMatWt(outputAct);
                    save(outputRecord);
                }
            }
        }

    }
}
